package com.example.springboottools.utils.image;

import com.alibaba.fastjson.JSON;
import com.example.springboottools.entiy.ExcelExportUtil;
import com.example.springboottools.utils.ReadExcel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * https://blog.51cto.com/u_16175494/10249570
 * https://www.cnblogs.com/hWang-97/p/17684693.html
 */
public class ImageSimilarityUtil {

    public static void main(String[] args) throws IOException {
        File imageFile1 = new File("C:\\Users\\SH102909\\Downloads\\cn1100124574EA_1_xnl.jpg");
        File imageFile2 = new File("C:\\Users\\SH102909\\Downloads\\cn1100124574EA_8_xnl.jpg");
        BufferedImage image1 = ImageIO.read(imageFile1);
        BufferedImage image2 = ImageIO.read(imageFile2);

        String hash1 = ImageSimilarityUtil.getHash(image1);
        String hash2 = ImageSimilarityUtil.getHash(image2);
        if (hash1.equals(hash2)) {
            System.out.println("图片重复");
        } else {
            System.out.println("图片不重复");
        }
        int distance = ImageSimilarityUtil.hammingDistance(hash1, hash2);

        if (distance <= 5) {
            System.out.println("图片重复");
        } else {
            System.out.println("图片不重复");
        }
//        String path = "D:\\staples\\日常记录\\工作记录\\2024\\07\\24\\pic\\文件名不一致重复主图.xls";
//        File excelFile = new File(path);
//        String[] nameStr = {"SKU","PIPICSZ","PIPICLK","PIC_SEQ","PIC_UM"};
//        List<Map<String, Object>> excelMapList = ReadExcel.readExcel1(excelFile, nameStr, 1, 0);
//        Map<String, List<Map<String, Object>>> collect = excelMapList.stream().collect(Collectors.groupingBy(map -> {
//            String sku = map.get("SKU").toString();
//            String picSeq = map.get("PIC_SEQ").toString();
//            String picUm = map.get("PIC_UM").toString();
//            return sku + picSeq + picUm;
//        }));
//        List<Map<String, List<Map<String, Object>>> > notSameMapList =new ArrayList<>();
//        AtomicInteger i = new AtomicInteger();
//        collect.forEach((k,v)->{
//            Map<String, List<Map<String, Object>>> stringListMap = compareMapImage(v);
//            System.out.println("已执行商品数量："+(i.getAndIncrement())+"执行商品编码："+k);
//            if (stringListMap.keySet().size()>1)notSameMapList.add(stringListMap);
//        });
//        List<Map> mapListAll = new ArrayList<>();
//        for (Map<String, List<Map<String, Object>>> stringListMap : notSameMapList) {
//           stringListMap.forEach((k1, v1) -> {
//               v1.forEach(map1 -> mapListAll.add(map1));
//           }
//           );
//        }
//        ExcelExportUtil excelExportUtil=new ExcelExportUtil();
//        String title="title";
//        //各个列的表头
//        String[] heardList={"商品编码","分辨率","文件名","序号","单位"};
//        //各个列的元素key值
//        String[] heardKey={"SKU","PIPICSZ","PIPICLK","PIC_SEQ","PIC_UM"};
//        //需要填充的数据信息
//        excelExportUtil.setTitle(title);
//        excelExportUtil.setHeardList(heardList);
//        excelExportUtil.setHeardKey(heardKey);
//        excelExportUtil.setData(mapListAll);
//        excelExportUtil.exportExportLocal("D:\\staples\\日常记录\\工作记录\\2024\\07\\24\\pic\\notSamePic.xls");
//        System.out.println(JSON.toJSONString(mapListAll));
    }
    public static Map<String,List<Map<String,Object>>> compareMapImage(List<Map<String,Object>> excelUrlList) {
        Map<String,List<Map<String,Object>>> hashMap = new HashMap<>();
        for (Map<String, Object> map : excelUrlList) {
            String fileName = map.get("PIPICLK").toString();
            String  url = "http://newvp-pic.staplescn.com/static_adv/ftp_product_img/" + fileName;
            BufferedImage image = null;
            try {
                 image = ImageIO.read(new URL(url));
            }catch (Exception e){
                if (hashMap.containsKey("error")){
                    List<Map<String, Object>> maps = hashMap.get("error");
                    maps.add(map);
                    hashMap.put("error",maps);
                }else {
                    hashMap.put("error",new ArrayList<>(Arrays.asList(map)));
                }
                continue;
            }
            String hash = ImageSimilarityUtil.getHash(image);
            if (hashMap.containsKey(hash)){
                List<Map<String, Object>> maps = hashMap.get(hash);
                maps.add(map);
                hashMap.put(hash,maps);
            }else {
                hashMap.put(hash,new ArrayList<>(Arrays.asList(map)));
            }
        }
        return hashMap;
    }
    public static String compareImage(List<String> imageUrlList) throws IOException {
        Map<String,List<String>> hashMap = new HashMap<>();
        for (String s : imageUrlList) {
            BufferedImage image = ImageIO.read(new URL(s));
            String hash = ImageSimilarityUtil.getHash(image);
            if (hashMap.containsKey(hash)){
                List<String> strings = hashMap.get(hash);
                strings.add(s);
                hashMap.put(hash,strings);
            }else {
                hashMap.put(hash,new ArrayList<>(Arrays.asList(s)));
            }
        }
        return null;
    }

    public static String getHash(BufferedImage image) {
        // 缩放图片
        Image scaledImage = image.getScaledInstance(8, 8, Image.SCALE_SMOOTH);
        BufferedImage scaledBufferedImage = new BufferedImage(8, 8, BufferedImage.TYPE_INT_RGB);
        scaledBufferedImage.getGraphics().drawImage(scaledImage, 0, 0, null);

        // 转换为灰度图
        int[][] grayArray = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                int pixel = scaledBufferedImage.getRGB(i, j);
                int r = (pixel >> 16) & 0xff;
                int g = (pixel >> 8) & 0xff;
                int b = pixel & 0xff;
                grayArray[i][j] = (r + g + b) / 3;
            }
        }

        // 计算平均灰度值
        int totalGray = 0;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                totalGray += grayArray[i][j];
            }
        }
        int avgGray = totalGray / 64;

        // 生成hash值
        StringBuilder hash = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                hash.append(grayArray[i][j] < avgGray ? "0" : "1");
            }
        }

        return hash.toString();
    }

    public static int hammingDistance(String hash1, String hash2) {
        int distance = 0;
        for (int i = 0; i < hash1.length(); i++) {
            if (hash1.charAt(i) != hash2.charAt(i)) {
                distance++;
            }
        }
        return distance;
    }
}
